// --------pranmari.s----------------------------------------------
// 22-4-91 cm   pipelined ranmar generator as pranmar except returns integer
//
//  ProtoType void pranmari( float *result, int n, int *ustore)
//
//   Any integer n allowed: it is number of random numbers returned
//   Pranmari exactly implements uni or pranmar but with result as bit
//    string with 24 msb reliable. So just ixfr then store as float.
//
//   15 cycles per random number in loop. ==>  10.5 cycles
//   Timing n=500:  11.2 cycles at DL 3-4-91   C-code: 106 cycles.
//
//

        resptr = r16
        n      = r17
        uptr   = r18
        ii     = r19
        ij     = r20
        c      = r21
        cd     = r22
        cm     = r23
        u      = r24
        r      = r25
        a      = r26
        b      = r27  // equiv to lduptr
        lduptr = r27  // equiv to b
        uiptr  = r28
        ujptr  = r29
        step   = r30
   // r31 is pointer

        fr      = f16
        ff      = f20
        fs1     = f24
        fs2     = f25
        fs3     = f26
        fs4     = f27
.align 4

_pranmari_::                            // fortran load point
        ld.l    0(n),   n               // pointer to value

_pranmari::                             // C entry

     // uptr: u[98],c,  cd, cm, ui,  uj
     //       0     99  100 101 102  103  words (address * 4)
        ld.l    408(uptr),ii
        ld.l    412(uptr),ij
        ld.l    396(uptr),c
        ld.l    400(uptr),cd
        ld.l    404(uptr),cm

        adds    -4,r0,  step            // bla decrements by 4

        adds    -4,resptr,resptr        // for auto increment store

//--------use ii,ij down to ii = 0 ready for loop---------------------

      shl   2,ii,ii              // * 4 for word addresses
      shl   2,ij,ij

start: adds   -1,n,n           // test at start so 0 pass OK
         bc Exit

      ld.l  ij(uptr),b
      subu  c,cd,c
      ld.l  ii(uptr),a
       bnc.t  donexts                  // if c-cd < 0 CC clear so do next (addu)
           addu  c,cm,c                // skipped if CC  set
donexts:
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs1
      adds  ii,uptr,lduptr
      st.l  u,0(lduptr)               // no reg+reg addressing available
      adds  -4,ij,ij
       bc.t  ij96s
             or    384,r0,ij
ij96s:
      adds -4,ii,ii                   // sets CC if ii < 0: so set 96
      fst.l fs1,4(resptr)++
         bnc       start

.align 8
// falls through here with ii = 96

// --------------Start of 97--------all in DIM-------------------------
//--start with ii = 96, ij = 32
//      do 1+8*4 passes ij=32,31-27, ...,3-0.   ii=ij+64
// then  do 16*4 passes ii=63-58,57-54,..,3-0.  ij=ii+33
// finish with ii=96, ij=32 ready to be done.

LOOP:
        adds    -97,n,   n
         bc     tail                    // n < 97 left to do

      or     28,r0,ij               // bla step -4, last pass loop1 ij=-4
      adds   124,uptr,ujptr         // 4*31;  ujptr -16 at end of 4-loop

      subu  c,cd,c
      ld.l  260(ujptr),a               // cached loads
      ld.l   4(ujptr),b              // ij = 32    (31+1)*4 address
       bnc.t  donext00                 // if c-cd < 0 CC clear so do next
             addu  c,cm,c             // skipped if CC  set
donext00:
      subu  a,b,u
      subu  u,c,r
      ixfr  r,ff
      st.l  u,260(ujptr)               // no reg+reg addressing available
       bla   step,ij,loop1            // sets LCC        ij-4
      fst.l ff , 4(resptr)++         // can't combine 2 or 4 stores since
//-----------------------Fast bit--8*4 passes---------------------------
                                                                      //
//--decrement ijptr by 16 per loop1. ij=31 to 0 done (ii=ij+64)

loop1:

      subu  c,cd,c
      ld.l  256(ujptr),a               // cached loads
      ld.l   0(ujptr),b
       bnc.t  donext01                 // if c-cd < 0 CC clear so do next
             addu  c,cm,c             // skipped if CC  set
donext01:
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs1
      st.l  u,256(ujptr)

      subu  c,cd,c
      ld.l  252(ujptr),a               // cached loads
      ld.l  -4(ujptr),b
       bnc.t  donext02
             addu  c,cm,c
donext02:
      fst.l fs1, 4(resptr)++         // can't combine 2 or 4 stores since
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs2
      st.l  u,252(ujptr)

      subu  c,cd,c
      ld.l  248(ujptr),a               // cached loads
      ld.l  -8(ujptr),b
       bnc.t  donext03
             addu  c,cm,c
donext03:
      fst.l fs2, 4(resptr)++
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs3
      st.l  u,248(ujptr)

      subu  c,cd,c
      ld.l  244(ujptr),a               // cached loads
      ld.l -12(ujptr),b
       bnc.t  donext04
             addu  c,cm,c
donext04:
      fst.l fs3, 4(resptr)++
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs4
      st.l  u,244(ujptr)


      adds  -16,ujptr,ujptr
       bla   step,ij,loop1            //  ij-4  ,
      fst.l fs4, 4(resptr)++
                                                                       //
//-----------------------------------------------------------------------
//--start with ii = 63, ij = 96
// do 64 passes ii=63-58,57-54, ...,3-0.

      or     60,r0,ii               // bla step -4, last pass loop2 ii=-4
       bla   step,ii,loop2          // sets LCC        ii-4
      adds   252,uptr,uiptr         // 4*63;  uiptr -16 at end of 4-loop

//-----------------------Fast bit--16*4 passes---------------------------
loop2:                                                                 //

      subu  c,cd,c
      ld.l    0(uiptr),a               // cached loads
      ld.l  132(uiptr),b
       bnc.t  donext11
             addu  c,cm,c
donext11:
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs1
      st.l  u,  0(uiptr)

      subu  c,cd,c
      ld.l   -4(uiptr),a               // cached loads
      ld.l  128(uiptr),b
       bnc.t  donext12
             addu  c,cm,c
donext12:
      fst.l fs1, 4(resptr)++
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs2
      st.l  u, -4(uiptr)

      subu  c,cd,c
      ld.l   -8(uiptr),a               // cached loads
      ld.l  124(uiptr),b
       bnc.t  donext13
             addu  c,cm,c
donext13:
      fst.l fs2, 4(resptr)++
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs3
      st.l  u, -8(uiptr)

      subu  c,cd,c
      ld.l  -12(uiptr),a               // cached loads
      ld.l 120(uiptr),b
       bnc.t  donext14
             addu  c,cm,c
donext14:
      fst.l fs3, 4(resptr)++
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs4
      st.l  u,-12(uiptr)


      adds  -16,uiptr,uiptr
       bla   step,ii,loop2            //  ii-4  ,
      fst.l fs4, 4(resptr)++
                                                                   //
// clear pipe--------------------------------------------------------

      br LOOP
      nop


//-------------------End of 97---------------------------------------

tail:                            // enter with ii,ij set 96,..0 range
         adds    97,n,n          // n left to do
         or     128,r0,ij        // next ij = 32*4
      or     384,r0,ii           //      ii = 96*4 ;  left DIM

tailoop: adds   -1,n,n           // test at start so 0 pass OK
         bc Exit

      ld.l  ij(uptr),b
      subu  c,cd,c
      ld.l  ii(uptr),a
       bnc.t  donextt                // if c-cd < 0 CC clear so do next (addu)
             addu  c,cm,c            // skipped if CC  set
donextt:
      subu  a,b,u
      subu  u,c,r
      ixfr  r,fs1
      adds  ii,uptr,lduptr
      st.l  u,0(lduptr)               // no reg+reg addressing available
      adds  -4,ij,ij
       bc.t  ij96
             or    384,r0,ij          // ij = 96*4 if was negative (-4)
ij96:
      adds -4,ii,ii                   // can't have ii < 0
      fst.l fs1,4(resptr)++
         br       tailoop
        nop

Exit:      // ii,ij are ready for next but 4* too big
      shr   2,ii,ii
      shr   2,ij,ij

        st.l    ii,408(uptr)
        st.l    ij,412(uptr)
        st.l    c,396(uptr)

        bri   r1
       nop
